package com.winit.openapi.wh.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.Sort.Direction;
import com.winit.common.spi.command.SPICommand;
import com.winit.common.spi.context.CommandContext;
import com.winit.common.utils.Collections3;
import com.winit.oms.spi.inbound.InboundOrderService;
import com.winit.oms.spi.inbound.command.CreateOrUpdateDirectForcenoticeCommand;
import com.winit.oms.spi.inbound.command.CreateSelfInspectionOrderCommand;
import com.winit.oms.spi.inbound.command.MerchandiseOrderCommand;
import com.winit.oms.spi.inbound.command.ModifyInboundOrderCommand;
import com.winit.oms.spi.inbound.command.OperateByKeyCommand;
import com.winit.oms.spi.inbound.command.QuerySelftInspectionOrderCommand;
import com.winit.oms.spi.inbound.command.SaveOrUpdateSendPortInfoCommand;
import com.winit.oms.spi.inbound.command.SearchInboundOrderCommand;
import com.winit.oms.spi.inbound.command.UpdateInboundOrderByForecastWHTimeCommand;
import com.winit.oms.spi.inbound.command.UpdateOrderVerifyCommand;
import com.winit.oms.spi.inbound.command.VoidInboundOrderCommand;
import com.winit.oms.spi.inbound.vo.ExportInboundOrderVo;
import com.winit.oms.spi.inbound.vo.InboundEnumConstant;
import com.winit.oms.spi.inbound.vo.InboundOrderVo;
import com.winit.oms.spi.inbound.vo.InboundVoidOrderRecordVo;
import com.winit.oms.spi.inbound.vo.ResultVo;
import com.winit.oms.spi.inbound.vo.UpdateOrderVerifyVo;
import com.winit.oms.spi.order.command.OrderAndMerchandiseQueryCommand;
import com.winit.oms.spi.order.vo.OrderAndMerchandiseVo;
import com.winit.oms.spi.selfInspection.command.UpdateSlefInspectionOrderVerifyCommand;
import com.winit.oms.spi.selfInspection.vo.SelfInspectionOrderVo;
import com.winit.oms.spi.selfInspection.vo.UpdateSlefInspectionOrderVerifyVo;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.DateUtil;
import com.winit.openapi.util.ValidateUtil;
import com.winit.openapi.wh.builder.InboundOrderBuilder;
import com.winit.openapi.wh.builder.SelfInspectionOrderBuilder;
import com.winit.openapi.wh.validator.InboundOrderfieldValidator;
import com.winit.pms.spi.winit.WinitProductService;
import com.winit.pms.spi.winit.command.WinitProductQueryCommand;
import com.winit.pms.spi.winit.vo.WinitProduct;

/**
 * 海外仓入库单
 * 
 * @version <pre>
 * Author     Version       Date        Changes
 * dinghua.an   1.0         2015年11月10日     Created
 *
 * </pre>
 * @since 1.
 */
@Controller
@RequestMapping(value = "/wh/inboundOrder")
public class InboundOrderController extends BaseController {

    @Resource
    private InboundOrderService inboundOrderService;
    
    @Resource
    private WinitProductService productService;
    /**
     * 创建入库单 保存到草稿
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/saveAsDraft")
    public String saveAsDraft(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        ModifyInboundOrderCommand command = new ModifyInboundOrderCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            InboundOrderfieldValidator.validSaveAsDraftField(json);
            InboundOrderVo vo = InboundOrderBuilder.buildInboundOrder(json);
            vo.setOrderSource("SellerPortal");
            command.setInboundOrder(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口保存草稿基本信息
        String orderNo = inboundOrderService.modifyInboundOrderForDraft(command);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("orderNo", orderNo);
        responseMsg.setData(data);
        return SUCCESS;
    }
    
    
    /**
     * 创建入库单 保存直发信息到草稿
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/saveOrUpdateDirectForenotice")
    public String saveOrUpdateDirectForenotice(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
    	CreateOrUpdateDirectForcenoticeCommand command = new CreateOrUpdateDirectForcenoticeCommand();
    	Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json,"orderNo");
            String directInfoVersion = json.containsKey("directInfoVersion") ? json.getString("directInfoVersion"):"2.0";
            if(directInfoVersion.equals("1.0")){
            	ValidateUtil.validNotNull(json,"preparedOffPortDate");
            	ValidateUtil.validNotNull(json,"preparedArrivePortDate");
            	command = InboundOrderBuilder.buildDirectForenotice(json);
            }else{
                command = new CreateOrUpdateDirectForcenoticeCommand();
            	ValidateUtil.validNotNull(json,"expectedSendWarehouseWay");//预计送仓方式
            	ValidateUtil.validNotNull(json,"expectedSendwarehouseTime");//预计送仓时间
            	command.setExpectedSendWarehouseTime(json.getDate("expectedSendwarehouseTime"));
            	command.setOrderNo(json.getString("orderNo").trim());
            	String expectedSendWarehouseWay = json.getString("expectedSendWarehouseWay");
            	command.setExpectedSendWarehouseWay(expectedSendWarehouseWay);
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
    	
    	String orderNo = inboundOrderService.saveOrUpdateDirectForenotice(command);
    	Map<String, Object> data = new HashMap<String, Object>();
        data.put("orderNo", orderNo);
        responseMsg.setData(data);
        return SUCCESS;
    }
    

    /**
     * 创建入库单 继续
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/firstStepContinue")
    public String firstStepContinue(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        ModifyInboundOrderCommand command = new ModifyInboundOrderCommand();
        Object obj = requestMsg.getData();
        String loanNo = null;
        String isFinace = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            InboundOrderfieldValidator.validFirstStepField(json);
            InboundOrderVo vo = InboundOrderBuilder.buildInboundOrder(json);
            vo.setOrderSource("SellerPortal");
            command.setInboundOrder(vo);
            loanNo = vo.getLoanNo();
            isFinace = vo.getIsFinance();
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口保存草稿基本信息
        String orderNo = inboundOrderService.modifyInboundOrderForContinue(command);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("orderNo", orderNo);
        if ("Y".equals(isFinace)) {
            data.put("loanNo", loanNo);
        }
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 查询订单列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/list")
    public String list(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();

        SearchInboundOrderCommand command = null;

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = buildSearchOrderCommand(json);
            command.setSource(ApiConstant.SET_SOURCE);
            Searchable searchable = buildSearchablePageParams(json);
            searchable.addSort(new Sort(Direction.DESC, "CREATED"));
            command.setSearchable(searchable);
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildSearchablePageParams(null);
            command = new SearchInboundOrderCommand();
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());

        // 调用接口分页查询订单
        Page<InboundOrderVo> pagelist = inboundOrderService.queryInboundOrderByConditions(command);
        if (pagelist != null) {
            List<Map<String, Object>> datalist = buildOrderList(pagelist.getContent());

            Map<String, Object> pageMap = getPageParams(pagelist);

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            data.put("pageParams", pageMap.get("pageParams"));
            responseMsg.setData(data);
        }
        return SUCCESS;
    }
    
    /**
     * 导出订单列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/exportOrders")
    public String exportOrders(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();

        SearchInboundOrderCommand command = null;

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = buildSearchOrderCommand(json);
            command.setSource(ApiConstant.SET_SOURCE);
            Searchable searchable = buildSearchablePageParams(json);
            searchable.addSort(new Sort(Direction.DESC, "CREATED"));
            command.setSearchable(searchable);
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildSearchablePageParams(null);
            command = new SearchInboundOrderCommand();
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        
        if(null != command.getSearchable()){
        	command.getSearchable().setPage(1, Integer.MAX_VALUE);
        }
        command.setCtx(CommandContext.getContext());

        // 调用接口分页查询订单
        Page<ExportInboundOrderVo> pagelist = inboundOrderService.exportInboundOrderByConditions(command);
        if (pagelist != null) {
//            List<Map<String, Object>> datalist = buildOrderList(pagelist.getContent());

            Map<String, Object> pageMap = getPageParams(pagelist);

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", pagelist.getContent());
            data.put("pageParams", pageMap.get("pageParams"));
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 查询入库单详情
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryOrderDetails")
    public String queryOrderDetails(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        String orderNo = "";
        String entryWhType = "";
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            ValidateUtil.validNotNull(json, "entryWhType");
            orderNo = json.getString("orderNo");
            entryWhType = json.getString("entryWhType");
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 查询订单详情
        SearchInboundOrderCommand command = new SearchInboundOrderCommand();
        command.setCtx(CommandContext.getContext());
        command.setOrderNo(orderNo);
        command.setEntryWhType(entryWhType);
        InboundOrderVo inboundOrderVo = inboundOrderService.queryInboundOrderDetails(command);
        Map<String, Object> map = new HashMap<String, Object>();
        if (inboundOrderVo != null) {
            WinitProductQueryCommand queryCommand = new WinitProductQueryCommand();
            queryCommand.setCtx(CommandContext.getContext());
            queryCommand.setCode(inboundOrderVo.getWinitProductCode());
            WinitProduct product = productService.queryProduct(queryCommand);
            
            if(null != product){
                inboundOrderVo.setWinitProductCode(product.getCode());
                inboundOrderVo.setWinitProductName(product.getName());
            }
            
            map = InboundOrderBuilder.buildReturnInboundOrderInfo(inboundOrderVo);
        }
        responseMsg.setData(map);
        return SUCCESS;
    }
    
    /**
     * 查询入库单详情(API)
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryOrderDetail")
    public String queryOrderDetail(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        String orderNo = "";
        boolean  isIncludePackage = false;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            orderNo = json.getString("orderNo");
            if("Y".equals(json.getString("isIncludePackage"))){
            	isIncludePackage = true;
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 查询订单详情
        SearchInboundOrderCommand command = new SearchInboundOrderCommand();
        command.setCtx(CommandContext.getContext());
        command.setOrderNo(orderNo);
        InboundOrderVo inboundOrderVo = inboundOrderService.queryInboundOrderDetails(command);
        Map<String, Object> map = new HashMap<String, Object>();
        if (inboundOrderVo != null) {
            map = InboundOrderBuilder.buildReturnInboundOrderInfoForAPI(inboundOrderVo,isIncludePackage);
        }
        responseMsg.setData(map);
        return SUCCESS;
    }

    /**
     * 查询入库单详情
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryNeedReservationSendWhOrder")
    public String queryAllNeedReservationSendWhOrder(@ModelAttribute RequestMsg requestMsg,
                                                     @ModelAttribute ResponseMsg responseMsg) {
        SPICommand command = new SPICommand();
        command.setCtx(CommandContext.getContext());
        List<InboundOrderVo> inboundOrderList = inboundOrderService.queryAllNeedReservationSendWhOrder(command);

        List<Map<String, Object>> rslist = new ArrayList<Map<String, Object>>();
        Map<String, Object> map = null;
        for (InboundOrderVo inboundOrderVo : inboundOrderList) {
            map = InboundOrderBuilder.buildReturnInboundOrderInfo(inboundOrderVo);

            rslist.add(map);
        }

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("list", rslist);

        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 更新未提货订单 主要更新描述，物流计划、提货、验货信息
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/updateUnpickupOrder")
    public String updateUnpickupOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        ModifyInboundOrderCommand command = new ModifyInboundOrderCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;

            // 验证入参信息
            InboundOrderfieldValidator.validUnpickupOrderField(json);
            InboundOrderVo vo = InboundOrderBuilder.buildUnpickupInboundOrder(json);
            command.setInboundOrder(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 未提货订单修改物流信息、提货/验货信息
        ResultVo resultVo = inboundOrderService.modifyInboundOrderForDetail(command);
        responseMsg.setData(resultVo);
        responseMsg.setMsg("success");
        return SUCCESS;
    }

    /**
     * 作废单个订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/void")
    public String voidOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        VoidInboundOrderCommand command = new VoidInboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            ValidateUtil.validNotNull(json, "entryWhType");
            ValidateUtil.validNotNull(json, "type");
            command.setOrderNo(json.getString("orderNo"));
            command.setEntryWhType(json.getString("entryWhType"));
            command.setSource(ApiConstant.SET_SOURCE);
            command.setType(json.getString("type"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口作废订单
        inboundOrderService.voidInboundOrder(command);
        return SUCCESS;
    }

    /**
     * 提交订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/submit")
    public String submitOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        OperateByKeyCommand<String> command = new OperateByKeyCommand<String>();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            command.setKey(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口提交订单
        ResultVo resultVo = inboundOrderService.submitInboundOrder(command);
        if (resultVo != null) {
            responseMsg.setData(resultVo);
        }
        return SUCCESS;
    }

    /**
     * 导出
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/exportInboundOrder")
    public String exportInboundOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();

        SearchInboundOrderCommand command = null;

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = buildSearchOrderCommand(json);
            command.setSource(ApiConstant.SET_SOURCE);
            Searchable searchable = buildSearchablePageParams(json);
            command.setSearchable(searchable);
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildSearchablePageParams(null);
            command = new SearchInboundOrderCommand();
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());

        // 调用接口分页查询订单
        String filePath = inboundOrderService.exportInboundOrderDetail(command);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("filePath", filePath);
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 查询总包裹数，总商品数 总单品数
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/statisticsPackage")
    public String statisticsPackage(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        SearchInboundOrderCommand command = new SearchInboundOrderCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            command.setOrderNo(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        Map<String, Object> data = new HashMap<String, Object>();
        InboundOrderVo inboundOrderVo = inboundOrderService.statisticsPackage(command);
        if (inboundOrderVo != null) {
            data.put("orderPackageQty", inboundOrderVo.getOrderPackageQty());
            data.put("orderMerchandiseQty", inboundOrderVo.getOrderMerchandiseQty());
            data.put("orderItemQty", inboundOrderVo.getOrderItemQty());
        }
        responseMsg.setData(data);
        return SUCCESS;
    }

    private SearchInboundOrderCommand buildSearchOrderCommand(JSONObject requestData) {
        SearchInboundOrderCommand command = new SearchInboundOrderCommand();
        // orderNo,merchandiseCode,merchandiseName三选一
        if (requestData.containsKey("orderNo")) {
            command.setOrderNo(requestData.getString("orderNo"));
        } else if (requestData.containsKey("merchandiseCode")) {
            command.setMerchandiseCode(requestData.getString("merchandiseCode"));
        } else if (requestData.containsKey("merchandiseName")) {
            command.setMerchandiseName(requestData.getString("merchandiseName"));
        }
                                    
        if(requestData.containsKey("transportType")){
            command.setTransprotType(requestData.getString("transportType"));
        }
        if(requestData.containsKey("inspectionType")){
            command.setInspectionType(requestData.getString("inspectionType"));
        }
        // 业务伙伴编码
        if (requestData.containsKey("customerCode")) {
            command.setCustomerCode(requestData.getString("customerCode"));
        }
        // 客户订单号
        if (requestData.containsKey("customerOrderNo")) {
            command.setCustomerOrderNo(requestData.getString("customerOrderNo"));
        }
        // winitProductCode
        if (requestData.containsKey("winitProductCode")) {
            command.setWinitProductCode(requestData.getString("winitProductCode"));
        }
        // entryWhType
        if (requestData.containsKey("entryWhType")) {
            command.setEntryWhType(requestData.getString("entryWhType"));
        }
        // inspectionWhCode
        if (requestData.containsKey("inspectionWhCode")) {
            command.setInspectionWarehouseCode(requestData.getString("inspectionWhCode"));
        }
        // destWhCode
        if (requestData.containsKey("destWhCode")) {
            command.setDestinationWarehouseCode(requestData.getString("destWhCode"));
        }
        // status
        if (requestData.containsKey("status")) {
            command.setStatus(requestData.getString("status"));
        }
        // orderDateStart
        if (requestData.containsKey("orderDateStart")) {
            String orderDateStart = requestData.getString("orderDateStart");
            orderDateStart += " 00:00:00";
            Date from = DateUtil.parse2Date(orderDateStart, DateUtil.FULL_DATE_STRING);
            command.setDateFrom(from);
        }
        // orderDateEnd
        if (requestData.containsKey("orderDateEnd")) {
            String orderDateEnd = requestData.getString("orderDateEnd");
            orderDateEnd += " 23:59:59";
            Date to = DateUtil.parse2Date(orderDateEnd, DateUtil.FULL_DATE_STRING);
            command.setDateTo(to);
        }
        if (requestData.containsKey("mergeType")) {
            String mergeType = requestData.getString("mergeType");
            if (!InboundEnumConstant.OrderMergeType.INIT.getCode().equals(mergeType)
                && !InboundEnumConstant.OrderMergeType.MAIN.getCode().equals(mergeType)
                && !InboundEnumConstant.OrderMergeType.SUB.getCode().equals(mergeType)) {
                throw new ApiException(ErrorCode.FEILD_NOT_MATCH, "mergeType");
            } else {
                command.setMergeType(mergeType);
            }
        }
        if(requestData.containsKey("productType")){
            command.setProductType(requestData.getString("productType"));
        }

        return command;
    }

    private List<Map<String, Object>> buildOrderList(List<InboundOrderVo> datalist) {
        List<Map<String, Object>> rslist = new ArrayList<Map<String, Object>>();
        Map<String, Object> map = null;
        for (InboundOrderVo order : datalist) {
            WinitProductQueryCommand queryCommand = new WinitProductQueryCommand();
            queryCommand.setCtx(CommandContext.getContext());
            queryCommand.setCode(order.getWinitProductCode());
            WinitProduct product = productService.queryProduct(queryCommand);
            
            if(null != product){
                order.setWinitProductCode(product.getCode());
                order.setWinitProductName(product.getName());
            }
            map = InboundOrderBuilder.buildInboundOrderListPageVo(order);

            rslist.add(map);
        }
        return rslist;
    }

    /**
     * 更新预计到仓时间
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/updateForecastWHTime")
    public String updateForecastWHTime(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        UpdateInboundOrderByForecastWHTimeCommand command = new UpdateInboundOrderByForecastWHTimeCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;

            command.setForecastWarehouseTime(json.getString("forecastWarehouseTime"));
            if (json.containsKey("orderNo")) {
                command.setOrderNo(json.getString("orderNo"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        ResultVo resultVo = inboundOrderService.updateForecastWHTime(command);
        responseMsg.setData(resultVo);
        responseMsg.setMsg("success");
        return SUCCESS;
    }
    
    /**
     * 获取作废详情
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/getVoidOrderRecord")
    public String getVoidOrderRecord(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){
        Object obj = requestMsg.getData();
        VoidInboundOrderCommand command = new VoidInboundOrderCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            command.setOrderNo(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        // 调用接口查询作废订单详情
        InboundVoidOrderRecordVo vo = inboundOrderService.getVoidOrderRecord(command);
        responseMsg.setData(vo);
        responseMsg.setMsg("success");
        return SUCCESS;
    }
    
    @RequestMapping(value = "/verifyCommandValidator")
    public String verifyCommandValidator(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){
        Object obj = requestMsg.getData();
        UpdateOrderVerifyCommand command = new UpdateOrderVerifyCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            command.setOrderNo(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        
        UpdateOrderVerifyVo vo = inboundOrderService.verifyUpdateOrder(command);
        responseMsg.setData(vo);
        responseMsg.setMsg("success");
        return SUCCESS;
    }
    
    /**
     * 创建自验单
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/createSelfInspectionOrder")
    public String createSelfInspectionOrder(@ModelAttribute RequestMsg requestMsg,
                                            @ModelAttribute ResponseMsg responseMsg) {
        CreateSelfInspectionOrderCommand command = new CreateSelfInspectionOrderCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            command.setWinitOrderNo(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        String orderNo = inboundOrderService.createSelfInspectionOrder(command);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("orderNo", orderNo);
        responseMsg.setData(data);
        return SUCCESS;
    }
    
    /**
     * 校验能否修改箱单信息
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/verifySelfInspectionOrderValidator")
    public String verifySelfInspectionOrderValidator(@ModelAttribute RequestMsg requestMsg,
                                                     @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        UpdateSlefInspectionOrderVerifyCommand command = new UpdateSlefInspectionOrderVerifyCommand();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            command.setOrderNo(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        UpdateSlefInspectionOrderVerifyVo vo = inboundOrderService.verifyUpdateSlefInspectionOrder(command);
        responseMsg.setData(vo);
        responseMsg.setMsg("success");
        return SUCCESS;
    }
    
    /**
     * 创建或更新送港信息
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/saveOrUpdateSendPortInfo")
    public String saveOrUpdateSendPortInfo(@ModelAttribute RequestMsg requestMsg,
                                            @ModelAttribute ResponseMsg responseMsg) {
        SaveOrUpdateSendPortInfoCommand command = new SaveOrUpdateSendPortInfoCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json, "orderNo");
            ValidateUtil.validNotNull(json, "sendPortType");
            
            if(json.containsKey("sendPortDate")){
                command.setSendPortDate(json.getDate("sendPortDate"));
            }
            if(json.containsKey("containerNo")){
                command.setContainerNo(json.getString("containerNo"));
            }
            if(json.containsKey("sendPortType")){
                command.setSendPortType(json.getString("sendPortType"));
            }
            if(json.containsKey("pickupCartonAddrCode")){
                command.setPickupCartonAddrCode(json.getString("pickupCartonAddrCode"));
            }
            if(json.containsKey("sealNo")){
                command.setSealNo(json.getString("sealNo"));
            }
            //构建入参
            command.setOrderNo(json.getString("orderNo"));
            command.setSendPortType(json.getString("sendPortType"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        String orderNo = inboundOrderService.saveOrUpdateSendPortInfo(command);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("orderNo", orderNo);
        responseMsg.setData(data);
        return SUCCESS;
    }
    
    
    /**
     * 查询自验单列表
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/getSelfInspectionOrderList")
    public String getSelfInspectionOrderList(@ModelAttribute RequestMsg requestMsg,
                                            @ModelAttribute ResponseMsg responseMsg) {
        QuerySelftInspectionOrderCommand command = new QuerySelftInspectionOrderCommand();
        Object obj = requestMsg.getData();
        
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            Searchable searchable = buildSearchablePageParams(json);
            searchable.addSort(new Sort(Direction.DESC, "CREATED"));
            command.setSearchable(searchable);
            command.setStatus(json.getString("status"));
            command.setOrderNo(json.getString("orderNo"));
            command.setWarehouseEntryType(json.getString("warehouseEntryType"));
            command.setTransportType(json.getString("transportType"));
            command.setInspectionWarehouseCode(json.getString("inspectionWarehouseCode"));
            command.setDestinationWarehouseCode(json.getString("destinationWarehouseCode"));
            command.setWinitProductCode(json.getString("winitProductCode"));
            command.setStartOrderDate(json.getDate("startOrderDate"));
            String orderDate = DateUtil.parse2String(json.getDate("endOrderDate"), DateUtil.FULL_DATE_STRING2);
            command.setEndOrderDate(DateUtil.parse2Date(orderDate, DateUtil.FULL_DATE_STRING));
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildSearchablePageParams(null);
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        Page<SelfInspectionOrderVo> resultList = inboundOrderService.getSelfInspectionOrderList(command);
        Map<String, Object> data = new HashMap<String, Object>();
        responseMsg.setData(data);
        if (resultList != null) {
            Map<String, Object> pageMap = getPageParams(resultList);
            data.put("list", SelfInspectionOrderBuilder.buildReturnSelfInspectionOrderList(resultList.getContent()));
            data.put("pageParams", pageMap.get("pageParams"));
            responseMsg.setData(data);
        }
        return SUCCESS;
    }
    
    
    /**
     * 根据商品条码和客户编码查询商品订单信息
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryMerchandiseOrder")
    public String queryMerchandiseOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){
    	MerchandiseOrderCommand command = new MerchandiseOrderCommand();
    	Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            ValidateUtil.validNotNull(json,"merchandiseSerNo");
            ValidateUtil.validNotNull(json,"customerCode");
            command.setMerchandiseSerNo(json.getString("merchandiseSerNo"));
            command.setCustomerCode(json.getString("customerCode"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
    	List<InboundOrderVo> list = inboundOrderService.getMerchandiseOrder(command);
		responseMsg.setData(list);
		return SUCCESS;
    }
    
    /**
     * 
     * 根据单据号和单品条码查询入库单信息.
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryInfoByDocNoAndItemSerno")
    public String queryInfoByDocNoAndItemSerno(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){
        OrderAndMerchandiseQueryCommand command = new OrderAndMerchandiseQueryCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONArray) {
            List<OrderAndMerchandiseVo> list = new ArrayList<OrderAndMerchandiseVo>();
            JSONArray jsonArr = (JSONArray) obj;
            if (Collections3.isEmpty(jsonArr)) {
                return SUCCESS;
            }
            
            for (Object o : jsonArr) {
                JSONObject detail = (JSONObject) o;
                OrderAndMerchandiseVo vo = new OrderAndMerchandiseVo();
                // 单据号
                ValidateUtil.validNotNull(detail, "docNo");
                vo.setDocNo(detail.getString("docNo"));
                
                // 单品条码
                ValidateUtil.validNotNull(detail, "itemSerno");
                vo.setItemSerno(detail.getString("itemSerno"));
                list.add(vo);
            }
            command.setCtx(CommandContext.getContext());
            command.setOrderList(list);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        List<Object> result = inboundOrderService.queryInfoByDocNoAndItemSerno(command);
        responseMsg.setData(result);
        return SUCCESS;
    }
}
